package com.example.demo.service;

import com.example.demo.data.SxConfig;
import com.example.demo.vo.Boutlist;
import com.example.demo.vo.Boutlistdetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Created by ltian on 2020/1/20.
 */
@Service
@Slf4j
public class CoreService {

    @Autowired
    private PackService packService;

    @Autowired
    @Qualifier("secondaryJdbcTemplate")
    protected JdbcTemplate jdbcTemplate;

    /*
    提供的正则表达式, 排除 _7 _9
    "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z挂学警港澳领试超外0-9]{3,9}_(0|1|2|3|4|5|6|7|9|11|12)$|^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z0-9][A-Z0-9]{4}应急_(0|1|2|3|4|5|6|7|9|11|12)$|^默A00000_[9]$";
     */
    private String vehiclePatternString = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z挂学警港澳领试超外0-9]{3,9}_(0|1|2|3|4|5|6|11|12)$|^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z0-9][A-Z0-9]{4}应急_(0|1|2|3|4|5|6|11|12)$|^默A00000_[9]$";

    private Pattern vehiclePattern = Pattern.compile(vehiclePatternString);



    @Autowired
    private SxConfig config;

    // 返回是否有效的
    public boolean isValidatePlate(String plate) {
        if (plate == null) {
            return false;
        }

        if (vehiclePattern.matcher(plate).matches()) {
            return true;
        }
        return false;
    }


    @Transactional
    public int abort(Boutlist boutlist) {
        if (config.isReadonly()) {
            return 0;
        }
        String updateSql = "UPDATE " + config.getBoutlist() + " SET cTransPackName = ? WHERE listno = ?";
        int affetced = jdbcTemplate.update(updateSql, "999", boutlist.getListno());
        packService.afterAbort(boutlist);

        return affetced;
    }


    @Transactional
    public void doFix(Boutlist boutlist, long totalFee,
                      String entolllaneid,
                      String entolllanehex,
                      String exTolllandid,
                      String vehplate,
                      String invehplate,
                      String vehplateAuto,
                      String cardNo,
                      String passId,
                      List<Boutlistdetail> details) {
        if (config.isReadonly()) {
            return;
        }

        boolean updateTotal = false;
        long etcDiff = 0L;
        if (boutlist.getTotaltoll() != totalFee) {
            updateTotal = true;
            if (config.isETC()) {//ETC的场合不能修改主表金额
                // 把差额补到省份14上
                etcDiff = totalFee - boutlist.getTotaltoll();
                totalFee = boutlist.getTotaltoll();

                boolean canFix = false;
                for (Boutlistdetail detail : details) {
                    if (detail.getProvinceid().startsWith("14")) {
                        if (detail.getTollfee() > etcDiff) {
                            canFix = true;//可以修正金额
                            detail.setTollfee(detail.getTollfee() - etcDiff);
                            detail.setTollsupport(3L);
                            detail.setTollintervalscount(0L);
                            detail.setTollintervalsgroup(null);
                            detail.setTranstimegroup(null);
                            detail.setChargepaygroup(null);
                            detail.setChargefeegroup(null);
                            detail.setChargediscountgroup(null);
                            detail.setRateversiongroup(null);
                            detail.setSectiongroup(null);
                            detail.setSectionname(null);
                        }
                        break;
                    }
                }

                if (!canFix) {
                    int i = abort(boutlist);
                    log.warn("fix failed, abort:{}, etcDiff:{}, listno:{}", i, etcDiff, boutlist.getListno());
                    return;
                }
            }
        }

        if (config.isETC()) {
            int splitProvince = details.size();
            if (boutlist.getMediatype() == 1) {
                boutlist.setMediatype(2);
            }

            if (boutlist.getAlgorithmidentifier() == 0) {
                boutlist.setAlgorithmidentifier(1);
            }
            if (boutlist.getObusign() == 0) {
                boutlist.setObusign(boutlist.getElecardtype().intValue());
            }
            if (boutlist.getMultiprovince() == 0) {
                splitProvince = 0;
            }

            String updateSql = "UPDATE " + config.getBoutlist() +
                    " SET specialType=0,  vehclass=0,mediatype=?, Algorithmidentifier=?, Obusign=?,  entolllaneid = ?, entolllanehex=?,exTolllaneid=?, vehplate=?,invehplate=?, vehplateAuto=?, totalToll = ?, ptotalToll = ?, spare1 = ?, spare2 = ?, " +
                    "splitprovince =?, cardno = ?, passid = ?, optime=? WHERE listno = ?";
            jdbcTemplate.update(updateSql,
                    boutlist.getMediatype(), boutlist.getAlgorithmidentifier(), boutlist.getObusign(),
                    entolllaneid, entolllanehex,
                    exTolllandid, vehplate, invehplate, vehplateAuto,
                    totalFee, totalFee, boutlist.getPtotaltoll(), boutlist.getTotaltoll(), splitProvince,
                    cardNo, passId,boutlist.getOptime(),


                    boutlist.getListno());


        } else {
            String updateSql = "UPDATE " + config.getBoutlist() +
                    " SET specialType=0,payType=1,obuSign=1, vehclass=0, entolllaneid = ?,entolllanehex=? ,exTolllaneid=?, vehplate=?,invehplate=?, vehplateAuto=?, totalToll = ?, ptotalToll = ?, spare1 = ?, spare2 = ?, " +
                    "splitprovince =?, cardno = ?, passid = ? WHERE listno = ?";
            jdbcTemplate.update(updateSql, entolllaneid, entolllanehex, exTolllandid, vehplate, invehplate, vehplateAuto, totalFee, totalFee, boutlist.getPtotaltoll(), boutlist.getTotaltoll(), details.size(),
                    cardNo, passId, boutlist.getListno());
        }


        int deleteCount = jdbcTemplate.update("DELETE FROM " + config.getBoutlistDetail() + " WHERE listno = ?", boutlist.getListno());

        final String sql = "Insert INTO " + config.getBoutlistDetail() +
                "(listno,stationno,squaddate,provinceid,tollsupport,tollfee,tollintervalscount,tollintervalsgroup,transtimegroup,chargefeegroup,chargediscountgroup," +
                "rateversiongroup,sectiongroup,sectionname,chargepaygroup,receivetime,packname,creceivetime)" +
                " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";

        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Boutlistdetail detail = details.get(i);
                ps.setString(1, detail.getListno());

                if (detail.getStationno() == null) {
                    ps.setNull(2, Types.NUMERIC);
                } else {
                    ps.setLong(2, detail.getStationno());
                }

                if (detail.getSquaddate() == null) {
                    ps.setNull(3, Types.NUMERIC);
                } else {
                    ps.setLong(3, detail.getSquaddate());
                }

                ps.setString(4, detail.getProvinceid());

                if (detail.getTollsupport() == null) {
                    ps.setNull(5, Types.NUMERIC);
                } else {
                    ps.setLong(5, detail.getTollsupport());
                }

                if (detail.getTollfee() == null) {
                    ps.setNull(6, Types.NUMERIC);
                } else {
                    ps.setLong(6, detail.getTollfee());
                }

                if (detail.getTollintervalscount() == null) {
                    ps.setNull(7, Types.NUMERIC);
                } else {
                    ps.setLong(7, detail.getTollintervalscount());
                }

                ps.setString(8, detail.getTollintervalsgroup());
                ps.setString(9, detail.getTranstimegroup());
                ps.setString(10, detail.getChargefeegroup());
                ps.setString(11, detail.getChargediscountgroup());
                ps.setString(12, detail.getRateversiongroup());
                ps.setString(13, detail.getSectiongroup());
                ps.setString(14, detail.getSectionname());
                ps.setString(15, detail.getChargepaygroup());

                if (detail.getReceivetime() == null) {
                    ps.setNull(16, Types.DATE);
                } else {
                    ps.setDate(16, detail.getReceivetime());
                }

                ps.setString(17, detail.getPackname());

                if (detail.getCreceivetime() == null) {
                    ps.setNull(18, Types.DATE);
                } else {
                    ps.setDate(18, detail.getCreceivetime());
                }
//                ps.setInt(19, detail.getSpare1());
//                ps.setInt(20, detail.getSpare2());
//                ps.setInt(21, detail.getSpare3());
//                ps.setString(22, detail.getSpare4());
//                ps.setString(23, detail.getSpare5());
//                ps.setInt(24, detail.getTransfertag());

            }


            @Override
            public int getBatchSize() {
                return details.size();
            }
        });

        log.warn("=> fix data, listno: {}, updateTotal:{}: -> {},{}, delete:{}, insert:{}, etcDiff:{}",
                boutlist.getListno(), updateTotal, boutlist.getTotaltoll(), totalFee, deleteCount, details.size(), etcDiff);
    }


    public int updateOtherVehicle(int squaddate) {
        if (config.isReadonly()) {
            return 0;
        }
        if (!config.isETC()) {
            return 0;
        }

        String updateSql = "UPDATE " + config.getBoutlist() +
                " SET cTransPackName = ? WHERE squaddate=? AND instationno not in (select stdstationno from pstation) and vehclass > 1 and totaltoll<>0";
        return jdbcTemplate.update(updateSql, "999", squaddate);
    }

}
